fix(quota): project scoped override actions from final admission - #5370
Conversation
Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com> Co-authored-by: TRAE CLI <traecli@bytedance.com>
Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com> Co-authored-by: TRAE CLI <traecli@bytedance.com>
|
Self-review of head
|
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewed exact head: 2d21f98c19f6d9422cee022f999845614d546c3f; immutable merge base: 04bf6b6c1c1d37d3b19194c91efe5b4c4d9daa7d. 当前 LoopX pull_request_review_execution_contract_v2,policy revision 13,whole-PR 评审。结论 APPROVE。
动机
这是一个实际 CLI readback 矛盾:peer gate 的早期 override 可能仍显示 P0 network Todo,最终 capability/selection 却已选择 shell-only P1;已结算或待选择包也可能留下可执行-looking 动作。用户应能直接从最终 interaction 和选中 Todo 得到一致下一步,不应自行解释哪个字段更新。已关闭的 #5349 明确被本实现替代;这里按既有 TS migration RFC 验收有界投影修复,不把建议变成 claim、预留或新的执行权限。
改动思路
在所有 selection、capability、workspace、receipt、notification cooldown 决策之后,Python 最终 packet 调用现有 Effect transport 中的 TS quota projection。它复用 decodeInteractionContract,删掉早期 selected_action,只在最终 delivery_allowed 且存在有效 selected Todo 时取其 text。早期 admission 的 kind/from_state/to_state/reason 仍为历史诊断,receipt identity 与真正执行义务未重新决定。
具体改动
完整 7 文件为 126 行新增:18 行 typed quota rule、两处 Effect handler 注册、9 行 final-packet 接线、67 行 Python 回归、19 行 TS 测试以及双语现有 RFC checkpoint。没有新 capability/provider、持久字段、CLI 开关或宽 pipeline 迁移。repository reuse 检查覆盖早期 agent_scope、final packet、interaction decoder、diagnose 与 frontend/Lark callers;未发现另一个需要同步编辑的 override 动作 consumer。
关键代码讲解
quota/scoped_override.ts:8 projectScopedOverride:复制诊断对象后移除旧动作;复用 typed interaction decoder 防止矛盾 channel。delivery 时验证 todo_id/text;null selection 不虚构工作,不修改输入。quota/should_run_packet.py:1468 _build_quota_should_run_payload:放在 settled/active builder、scheduler 与 notification cooldown 之后,保证使用最终而非早期 admission 的权限事实。effect_runtime_handlers.ts:581 quota.scoped_override.project:注册到现有实际 Effect runtime,不新增 Python 决策副本或独立 transport。test_scoped_override_final_action.py:37 test_override_uses_final_capability_eligible_todo:同时覆盖 user_gate/user_action、能力差异和显式选择;settled、非法选择、缺能力、未 claim 的 selection-required 另有反例,receipt-bound Todo identity 保留。
对主干的风险
我运行相关 Python suites 84 passed,含 real-source scoped-gate fallback 的 Markdown/File/SQLite CLI 和 auxiliary gate paths;TS interaction tests 4 passed,control-plane typecheck、Ruff、19-source Mypy、changed-diff semantic advisory、完整 semantic smoke、diff whitespace 通过。验证使用 source-checkout 的实际 TS Effect runtime,不是返回预设 admission 的 mock。
独立同输入 base/head 矩阵 60 个完整 packet,覆盖两个 override kind、无 override/本 lane gate、三组能力、自动/显式/非法/receipt-bound/settled 选择。只有预期 30 个 scoped selected_action 字段更正或省略;其余 admission、selection、scheduler、receipt 和错误完全一致。对 scheduler hints 先解压 host-facts chunks,仅归一化其中生成时间,不删除其内容。独立 oracle 在旧 base 明确失败、当前 head 全部通过,预期来自“最终动作等于最终准入 Todo”的契约,不从 replacement 输出反推。
另用隔离真实 Markdown registry、原生 quota should-run --codex-app --turn-instance-id ... --todo-id ... 做四个 base/head CLI 场景,验证 shell-only P1 的更正、无能力时不展示动作、无 override 控制及 receipt binding,源 Todo 文件未变化。第一次探针遗漏必需 Turn 参数,只证明 parser 拒绝;补齐参数后才验证实际路径。完整观察只归一化 fixture-root、生成时间及本次随机 event ID;settlement effect/Goal/agent/Todo/Turn identity 保留且一致。实际 CLI 的 user_action 场景未产生早期 override,不能冒称该分支的 native coverage;其 typed final-builder 分支由上述独立矩阵覆盖。
语义与 CI 对齐
这是明确默认 readback 修复:两个 scoped override 的 optional selected_action 从最终选中 Todo 派生;non-delivery 时缺省。双语 RFC 已披露这一变化。to_state=eligible 是早期诊断,不是当前执行授权;machine-enforced must_attempt/delivery_allowed 仍由 interaction owner 决定,非“guidance”。新 internal Effect operation 延伸既有 typed quota owner,不创建共享 actor lifecycle 或第二状态源。未涉及 UI config/editor,因此没有 frontend/Lark companion;diagnose 保留原诊断 bag、权限和 Todo authoring 入口均不变。未改 PostgreSQL store 或持久 writer,不将 File/SQLite 测试当成 PG refactor 资格。wait_for_ci=false,未获取、轮询或等待远端 CI。
我的整体评价
APPROVE。最小有用修复是从既有最终 authority 派生诊断,而非重新排序 Todo、改 claim-next、丢弃历史 admission 或要求用户额外确认。future-facing pass 已落实取消 final action 的独立早期真相源,并复用 typed decoder/transport;剩余 Python route/primary-action builder 的迁移仍由既有 RFC 承接,不是本修复完成声明。零新持久化和开关,回退为这一个 projection 接线即可。批准后执行 capability approval-closeout;不授权 merge、不做自合并。
English verdict: APPROVE - exact head 2d21f98. Scoped override actions now follow final admission and selection without changing execution authority or receipt identity. 84 Python and 4 TS tests pass; 60 complete base/head packets plus four native quota CLI scenarios validate the intentional diagnostic delta and unchanged controls. Remote CI, broader TS migration and merge readiness are not claimed.
Goal And Delivered Outcome
A peer-scoped User gate could leave
agent_scoped_*_override.selected_actionpointing to a P0 Todo requiring network even after quota selected a shell-only P1 Todo. Settled and selection-required packets could also retain that executable-looking text.The final packet now derives this optional field from the final selected Todo through a typed quota projection, only when the final interaction permits delivery. Gate admission diagnostics and receipt binding remain intact. This implements the bounded correction under the existing TypeScript control-plane migration RFC and supersedes #5349. Base:
main.Scope And Continuation
Complete within this scope: both scoped User gate/action overrides, capability filtering, explicit selection, rejected selection and settled readback. The existing quota owner is sufficient; no capability, provider or wire schema is added. This deliberately changes the diagnostic field on non-delivery packets: consumers must tolerate its absence.
The future-facing pass removes the override's independent final action authority while keeping early gate admission intact. Remaining Python route/primary-action builders and recommendation reservation remain outside this correction; the existing migration RFC retains those broader boundaries.
Validation
8295cde84; final head adds only the bilingual RFC checkpoint.quota-agent-scoped-user-gate-smoke.pypasses.npm run typecheck:control-plane, semantic inventory advisory, maintainability ratchet andgit diff --check.loopx check: public-boundary scan clean; zero errors. Two unrelated pre-existing local-state warnings are outside this diff.Coverage targets the actual quota builder and its TS Effect runtime transport. The premerge selector was previewed; the risk-based checks above were executed directly. No storage mutation changes, so provider integration is not applicable. No frontend/Lark consumer independently reads this override action; existing interaction authority remains the execution contract. Maintainer review/merge remains required.
Frontend / Visual Evidence
UI impact: none. This changes CLI diagnostic JSON and RFC body text, with no first-screen or visual change.
Shared-authority RFC fixture impact
The existing synthetic quota/Todo shapes are retained. Changed dimension: final admitted action versus early peer-gate diagnostic candidate. Receipt identity and selected-Todo fields are preserved. Provider promotion and three-arm rehearsal are not applicable to this readback correction.
Boundary Checklist